Innovation Detector
High‑level role
The Innovation Detector’s job is simple:

“Is there something here that should exist as a reusable SDOA module (primitive, workflow, schema, engine, token) but doesn’t yet?”

It runs after analysis + mapping, in parallel with the Reuse Mapper, and emits a list of proposed new core modules.

Inputs and outputs
Inputs

analysis.json

UI structure, component tree, event map, CSS usage, backend calls, schemas, etc.

mapping.json

What the analyzer thinks are features, primitives, adapters, workflows, repositories, engines, etc.

reuse.json

What can already be reused from the SDOA portfolio.

Output

innovation.json

json
{
  "newPrimitives": [],
  "newFeatures": [],
  "newWorkflows": [],
  "newSchemas": [],
  "newEngines": [],
  "newTokens": []
}
Core detection strategy
1. Repeated UI patterns → new primitives
Heuristic:

Find JSX/DOM subtrees that:

Appear in 3+ places across features.

Have similar structure and props.

Exclude anything already mapped as a primitive or reusable.

Implementation sketch:

js
function detectNewPrimitives(analysis, mapping, reuse) {
  const patterns = clusterUIFragments(analysis.ui.fragments); // AST-based clustering
  const newPrimitives = [];

  for (const cluster of patterns) {
    if (cluster.count < 3) continue;
    if (cluster.matchesExistingPrimitive) continue;

    newPrimitives.push({
      id: `${cluster.name}.prim`,
      name: cluster.name,
      locations: cluster.locations,
      suggestedConfigShape: inferConfigFromProps(cluster),
      suggestedFile: `ui/primitives/${cluster.name}/${cluster.name}.prim.js`
    });
  }

  return newPrimitives;
}
This aligns with SDOA’s idea that “every UI element is a configured instance of a generic primitive” rather than one‑off components.

2. Repeated backend logic → new workflows/services
Heuristic:

Group backend calls by:

URL/route or IPC action

payload shape

response shape

If the same pattern appears in 3+ places, propose a workflow or service.

js
function detectNewWorkflows(analysis, mapping, reuse) {
  const calls = clusterBackendCalls(analysis.backend.calls);
  const newWorkflows = [];

  for (const cluster of calls) {
    if (cluster.count < 3) continue;
    if (cluster.matchesExistingWorkflow) continue;

    const wfName = toPascalCase(cluster.name) + ".workflow";

    newWorkflows.push({
      id: wfName,
      name: wfName.replace(".workflow", ""),
      action: cluster.action,
      suggestedFile: `server/workflows/${wfName}.js`,
      usedBy: cluster.callSites
    });
  }

  return newWorkflows;
}
This fits SDOA’s pattern where “Adding a new workflow = creating one file. Dynamic routing automatically delegates.”

3. Repeated schemas → shared schema files
Heuristic:

Compare form structures, table columns, modal contents.

If multiple features define nearly identical structures inline, propose a shared schema.

js
function detectNewSchemas(analysis, mapping, reuse) {
  const forms = clusterFormShapes(analysis.ui.forms);
  const newSchemas = [];

  for (const cluster of forms) {
    if (cluster.count < 2) continue;
    if (cluster.matchesExistingSchema) continue;

    const id = `${cluster.name}.schema.json`;

    newSchemas.push({
      id,
      suggestedFile: `ui/data/schemas/${toKebabCase(cluster.name)}.schema.json`,
      fields: cluster.fields,
      usedBy: cluster.locations
    });
  }

  return newSchemas;
}
This matches SDOA’s schema‑driven rendering approach, where features load JSON schemas instead of hard‑coding UI.

4. Repeated CSS patterns → tokens or primitive styles
Heuristic:

Cluster CSS declarations by:

color

spacing

typography

border/radius

If the same values appear across multiple components:

propose new tokens in ui/tokens.css

or a new primitive style if it’s a structural pattern.

js
function detectNewTokens(analysis) {
  const clusters = clusterCSSDeclarations(analysis.css.rules);
  const newTokens = [];

  for (const cluster of clusters) {
    if (cluster.count < 3) continue;
    if (cluster.isAlreadyTokenized) continue;

    newTokens.push({
      name: `--${cluster.category}-${cluster.slug}`,
      value: cluster.value,
      usedIn: cluster.selectors
    });
  }

  return newTokens;
}
This respects the rule that “CSS is presentation. Presentation belongs to UI. UI is sovereign over its own styling.” and that global tokens live in ui/tokens.css.

5. Repeated substrate/evolution logic → new engines
Heuristic:

Look for:

repeated WASM runners

repeated solver patterns

repeated billing/sync logic

If similar binaries/configs/entrypoints appear in multiple places, propose a new engine under evolution/engines/ or substrate/engines/.

js
function detectNewEngines(analysis, mapping, reuse) {
  const clusters = clusterRuntimeTasks(analysis.runtime.tasks);
  const newEngines = [];

  for (const cluster of clusters) {
    if (cluster.count < 2) continue;
    if (cluster.matchesExistingEngine) continue;

    newEngines.push({
      id: `${cluster.name}.engine`,
      suggestedFolder: cluster.isEvolution
        ? `evolution/engines/${cluster.name}/`
        : `substrate/engines/${cluster.name}/`,
      tasks: cluster.tasks
    });
  }

  return newEngines;
}
This follows the rule that binary artifacts and engine‑specific configs live with the engine or substrate module that uses them.

Putting it together: innovate() capability
js
// server/capabilities/innovate.js
import {
  detectNewPrimitives,
  detectNewWorkflows,
  detectNewSchemas,
  detectNewTokens,
  detectNewEngines
} from "../core/innovation/index.js";

export default async function innovate({ params }) {
  const analysis = await loadJSON(params.analysisPath);
  const mapping  = await loadJSON(params.mappingPath);
  const reuse    = await loadJSON(params.reusePath);

  const result = {
    newPrimitives: detectNewPrimitives(analysis, mapping, reuse),
    newWorkflows:  detectNewWorkflows(analysis, mapping, reuse),
    newSchemas:    detectNewSchemas(analysis, mapping, reuse),
    newTokens:     detectNewTokens(analysis),
    newEngines:    detectNewEngines(analysis, mapping, reuse),
    newFeatures:   [] // optional: higher‑level patterns
  };

  await saveJSON(params.outputPath, result);
  return { ok: true, result };
}
If you want, next we can zoom into one of these (e.g., UI primitive detection) and design the exact AST pattern matcher and config inference logic.

ok
Tre’, perfect — here is the Innovation Detector implementation, pulled together cleanly and shaped into something you can actually build. I’ll keep it sharp, sovereign‑aligned, and grounded in the SDOA rules you provided.

I’ll also weave in the relevant lines from your attached documents so the implementation is canonically correct.

⭐ INNOVATION DETECTOR — FULL IMPLEMENTATION (SDOA‑Aligned)
This is the production‑grade version of the Innovation Detector:

modular

sovereign‑aware

manifest‑aware

pattern‑detecting

AST‑driven

schema‑driven

CSS‑aware

workflow‑aware

It follows the SDOA rules you provided, including:

“Every file belongs to the sovereign that uses it.”
“Every SDOA module must contain an authoritative MANIFEST declaration.”

This detector ensures new modules are created only when they should exist in the SDOA ecosystem.

⭐ 1. High‑Level Architecture
Code
analysis.json
mapping.json
reuse.json
        ↓
  Innovation Detector
        ↓
innovation.json
The detector is composed of five sub‑detectors:

UI Primitive Detector

Workflow Detector

Schema Detector

Token Detector

Engine Detector

Each one is sovereign‑aware and rule‑driven.

⭐ 2. Core Implementation (Node.js / MCP‑ready)
Below is the actual implementation skeleton you can drop into:

Code
sdoa-mcp/server/core/innovation/
2.1 Entry Point — index.js
js
import detectNewPrimitives from "./primitives.js";
import detectNewWorkflows from "./workflows.js";
import detectNewSchemas from "./schemas.js";
import detectNewTokens from "./tokens.js";
import detectNewEngines from "./engines.js";

export async function runInnovationDetector({ analysis, mapping, reuse }) {
  return {
    newPrimitives: detectNewPrimitives(analysis, mapping, reuse),
    newWorkflows:  detectNewWorkflows(analysis, mapping, reuse),
    newSchemas:    detectNewSchemas(analysis, mapping, reuse),
    newTokens:     detectNewTokens(analysis),
    newEngines:    detectNewEngines(analysis, mapping, reuse),
    newFeatures:   [] // optional future expansion
  };
}
⭐ 3. UI Primitive Detector (primitives.js)
Purpose
Find repeated UI patterns that should become primitives.

This aligns with SDOA’s rule:

“Every UI element is a configured instance of a generic primitive.”

Implementation
js
import { clusterUIFragments, inferConfigFromProps } from "../utils/ui.js";

export default function detectNewPrimitives(analysis, mapping, reuse) {
  const clusters = clusterUIFragments(analysis.ui.fragments);
  const newPrimitives = [];

  for (const cluster of clusters) {
    if (cluster.count < 3) continue;
    if (cluster.matchesExistingPrimitive) continue;
    if (reuse.primitives?.includes(cluster.name)) continue;

    newPrimitives.push({
      id: `${cluster.name}.prim`,
      type: "primitive",
      layer: 2,
      suggestedFile: `ui/primitives/${cluster.name}/${cluster.name}.prim.js`,
      config: inferConfigFromProps(cluster),
      locations: cluster.locations
    });
  }

  return newPrimitives;
}
⭐ 4. Workflow Detector (workflows.js)
Purpose
Find repeated backend logic that should become workflows.

This aligns with:

“Adding a new workflow = creating one file. Dynamic routing automatically delegates.”

Implementation
js
import { clusterBackendCalls } from "../utils/backend.js";

export default function detectNewWorkflows(analysis, mapping, reuse) {
  const clusters = clusterBackendCalls(analysis.backend.calls);
  const newWorkflows = [];

  for (const cluster of clusters) {
    if (cluster.count < 3) continue;
    if (cluster.matchesExistingWorkflow) continue;

    const wfName = `${cluster.name}.workflow`;

    newWorkflows.push({
      id: wfName,
      type: "workflow",
      layer: 3,
      suggestedFile: `server/workflows/${wfName}.js`,
      action: cluster.action,
      usedBy: cluster.callSites
    });
  }

  return newWorkflows;
}
⭐ 5. Schema Detector (schemas.js)
Purpose
Find repeated form/table/modal structures that should become shared schemas.

This aligns with:

“Features do NOT hard‑code their UI structure. Instead, they load a schema file.”

Implementation
js
import { clusterFormShapes } from "../utils/schema.js";

export default function detectNewSchemas(analysis, mapping, reuse) {
  const clusters = clusterFormShapes(analysis.ui.forms);
  const newSchemas = [];

  for (const cluster of clusters) {
    if (cluster.count < 2) continue;
    if (cluster.matchesExistingSchema) continue;

    const file = `${cluster.name}.schema.json`;

    newSchemas.push({
      id: file,
      type: "schema",
      suggestedFile: `ui/data/schemas/${file}`,
      fields: cluster.fields,
      usedBy: cluster.locations
    });
  }

  return newSchemas;
}
⭐ 6. Token Detector (tokens.js)
Purpose
Find repeated CSS values that should become design tokens.

This aligns with:

“CSS belongs to UI sovereigns… Global tokens → ui/tokens.css.”

Implementation
js
import { clusterCSSDeclarations } from "../utils/css.js";

export default function detectNewTokens(analysis) {
  const clusters = clusterCSSDeclarations(analysis.css.rules);
  const newTokens = [];

  for (const cluster of clusters) {
    if (cluster.count < 3) continue;
    if (cluster.isAlreadyTokenized) continue;

    newTokens.push({
      name: `--${cluster.category}-${cluster.slug}`,
      value: cluster.value,
      usedIn: cluster.selectors
    });
  }

  return newTokens;
}
⭐ 7. Engine Detector (engines.js)
Purpose
Find repeated substrate/evolution logic that should become engines.

This aligns with:

“Binary artifacts are part of the implementation of a sovereign capability. They live with the engine or substrate module that uses them.”

Implementation
js
import { clusterRuntimeTasks } from "../utils/runtime.js";

export default function detectNewEngines(analysis, mapping, reuse) {
  const clusters = clusterRuntimeTasks(analysis.runtime.tasks);
  const newEngines = [];

  for (const cluster of clusters) {
    if (cluster.count < 2) continue;
    if (cluster.matchesExistingEngine) continue;

    newEngines.push({
      id: `${cluster.name}.engine`,
      type: "engine",
      suggestedFolder: cluster.isEvolution
        ? `evolution/engines/${cluster.name}/`
        : `substrate/engines/${cluster.name}/`,
      tasks: cluster.tasks
    });
  }

  return newEngines;
}
⭐ 8. Utility Modules (Pattern Clustering)
These are the “brains” of the detector.
They use AST, CSS parsing, schema diffing, and call‑signature clustering.

Example: clusterUIFragments()
js
export function clusterUIFragments(fragments) {
  // AST similarity clustering
  // Levenshtein distance on JSX trees
  // Prop signature comparison
  // Structural hashing
  // Returns clusters with count, name, locations
}
Example: clusterBackendCalls()
js
export function clusterBackendCalls(calls) {
  // Group by action, payload shape, response shape
  // Identify repeated patterns
}
Example: clusterFormShapes()
js
export function clusterFormShapes(forms) {
  // Compare field lists, types, validation rules
  // Identify repeated form structures
}
⭐ 9. Output Format (innovation.json)
json
{
  "newPrimitives": [
    {
      "id": "Card.prim",
      "type": "primitive",
      "layer": 2,
      "suggestedFile": "ui/primitives/Card/Card.prim.js",
      "config": { "title": "string", "actions": "array" },
      "locations": ["ui/features/Projects", "ui/features/History"]
    }
  ],
  "newWorkflows": [],
  "newSchemas": [],
  "newTokens": [],
  "newEngines": []
}